package bjfuwjx.exp5;
import javax.swing.*;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;

public class Server extends JFrame {
    private static final int PORT=7608;
    private CopyOnWriteArrayList<ClientConn> ccList=new CopyOnWriteArrayList<>();
    private HashMap<Integer,String> mp=new HashMap<>();
    private ServerSocket ss=null;
    private boolean isStart=false;
    public Server() {
        startServer();
    }
    public void startServer(){
        try {
            try {
                ss = new ServerSocket(PORT);
                isStart = true;
            } catch (IOException e) {
                e.printStackTrace();
            }
            new Thread(new Control()).start();
            while (isStart) {
                if (!ss.isClosed()){
                    Socket s = ss.accept();
                    ccList.add(new ClientConn(s));
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    class Control implements Runnable{
        private BufferedReader bf;
        @Override
        public void run(){
            while (true){
                p=0;
                System.out.println("end——结束程序");
                System.out.println("count——聊天者数量");
                System.out.println("chatters——聊天者");
                System.out.println("kickout+空格+昵称——踢出聊天室");
                bf=new BufferedReader(new InputStreamReader(System.in));
                String order=getStrFromConsole();
                if (order.equals("end")){
                    try {
                        bf.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    isStart=false;
                    System.exit(0);
                    break;
                }
                else if (order.equals("count")){
                    System.out.println(ccList.size());
                }
                else if (order.equals("chatters")){
                    for (int i=0;i<ccList.size();i++){
                        System.out.println(mp.get(ccList.get(i).s.getPort()));
                    }
                }
                else{
                    int idx=order.indexOf(' ');
                    idx++;
                    String name="";
                    while (idx<order.length()){
                        name+=order.charAt(idx);
                        idx++;
                    }
                    int port=0;
                    for (Integer i:mp.keySet()){
                        if (mp.get(i).equals(name)){
                            port=i;
                            break;
                        }
                    }
                    Iterator<ClientConn> it=ccList.iterator();
                    ClientConn c=null;
                    while (it.hasNext()) {
                        ClientConn o=it.next();
                        if (o.s.getPort()!=port){
                            o.send(mp.get(port)+" 被踢出聊天室\n");

                        }
                        else{
                            o.send("您已被踢出聊天室\n");
                            c=o;
                            p=1;
                            q=1;
                        }
                    }
                    mp.remove(c.s.getPort());
                    ccList.remove(c);
                    q=0;
                }
            }
        }
        private String getStrFromConsole(){
            try {
                return bf.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return "";
        }
    }
    private int p=0;
    private int q=0;
    class ClientConn implements Runnable{
        Socket s;
        public ClientConn(Socket s) {
            this.s=s;
            (new Thread(this)).start();
        }
        @Override
        public void run() {
            p=0;
            try {
                while (isStart) {
                    DataInputStream dis=new DataInputStream(s.getInputStream());
                    String str=dis.readUTF();
                    Date day=new Date();
                    SimpleDateFormat df=new SimpleDateFormat("HH:mm:ss");
                    String strSend="";
                    int idx=str.indexOf(" ");
                    if (idx!=-1&& str.startsWith("欢迎 ", idx+1)){
                        String name="";
                        for (int i=0;i<idx;i++)
                            name+=str.charAt(i);
                        int f=0;
                        for (Integer i:mp.keySet()){
                            if (mp.get(i).equals(name)){
                                f=1;
                                break;
                            }
                        }
                        if (f==1){
                            ClientConn o= ccList.get(ccList.size()-1);
                            o.send("昵称冲突，请更改昵称后重新进入\n");
                            ccList.remove(ccList.size()-1);
                            p=1;
                            continue;
                        } else{
                            String t=str.substring(idx);
                            strSend="["+df.format(day)+"] "+t+"\n";
                        }
                    }
                    else{
                        String name="";
                        String t=str.substring(idx);
                        for (int i=0;i<idx;i++)
                            name+=str.charAt(i);
                        mp.put(s.getPort(),name);
                        strSend ="["+df.format(day)+"] "+name+"说: " +t+ "\n";
                    }
                    Iterator<ClientConn> it=ccList.iterator();
                    while (it.hasNext()) {
                        ClientConn o=it.next();
                        o.send(strSend);
                    }
                }
            } catch (SocketException e) {
                int t=s.getPort();
                ClientConn c = null;
                if (q!=1||p==0) {
                    for (int i = 0; i < ccList.size(); i++) {
                        ClientConn o = ccList.get(i);
                        if (o.s.getPort() != t&&mp.get(s.getPort())!=null) {
                            o.send(mp.get(s.getPort()) + " 离开了聊天室\n");
                            p=1;
                        } else {
                            c = o;
                        }
                    }
                    mp.remove(c.s.getPort());
                    ccList.remove(c);
                }
            }
            catch (IOException e) {
                System.out.println("服务器中断了!");
                e.printStackTrace();
            }
        }
        public void send(String str){
            try{
                DataOutputStream dos=new DataOutputStream(this.s.getOutputStream());
                dos.writeUTF(str);
                dos.flush();
            } catch (IOException e){
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        new Server();
    }
}